/**
 * @Description RegisterController.java
 * @author xu_cc [18724000100@163.com]
 * @date 创建时间：2017年9月19日 下午4:52:13
 */
package com.solution.pc.home.controller;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.esotericsoftware.minlog.Log;
import com.solution.admin.auth.service.UserService;
import com.solution.admin.customer.constants.CustomerConstants;
import com.solution.admin.customer.entity.CompanyEntity;
import com.solution.admin.customer.entity.CustomerEntity;
import com.solution.admin.customer.service.CompanyService;
import com.solution.admin.customer.service.CustomerService;
import com.solution.admin.home.service.RedisService;
import com.solution.admin.settings.entity.KeyMapEntity;
import com.solution.admin.settings.service.KeyMapService;
import com.solution.common.constants.PublicStatus;
import com.solution.common.constants.PublicStatus.STATUS;
import com.solution.common.constants.PublicStatus.SysCode;
import com.solution.common.constants.PublicStatus.USER_APPROVE_STATUS;
import com.solution.common.entity.BaseReturn;
import com.solution.common.utils.AuthCodeUtils;
import com.solution.common.utils.RandomUtils;
import com.solution.common.utils.UUIDUtil;
import com.solution.common.utils.ip.IPUtils;
import com.solution.common.utils.sms.AliyunSmsUtils;
import com.solution.common.utils.string.StringUtil;
import com.solution.pc.home.constants.HomeConstants.SmsTemplateType;
import com.solution.pc.home.constants.HomeConstants.UserDataKey;
import com.solution.wx.my.constants.MyConstants;

/**
 * 用户注册
 * 
 * @author xu_cc
 * @date 创建时间：2017年9月21日 下午4:07:55
 */
@RequestMapping("/reg")
@Controller
public class RegisterController {
	private static final Logger logger = LoggerFactory.getLogger(RegisterController.class);

	@Autowired
	UserService userService;

	@Autowired
	CustomerService customerService;

	@Autowired
	CompanyService companyService;

	@Autowired
	RedisService redisService;
	
	/**
	 * 数据字典业务层组件
	 */
	@Autowired
	private KeyMapService keyMapService;

	/**
	 * 验证数据
	 * 
	 * @param request
	 * @param response
	 * @param type
	 * @param value
	 * @return boolean
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月21日 上午12:27:52
	 */
	@RequestMapping("/doCheckData")
	@ResponseBody
	public boolean doCheckData(String mobile, String type, String value) {
		try {
			if (StringUtil.isEmpty(type) || StringUtil.isEmpty(value)) {
				return false;
			}
			if (UserDataKey.VALID_TYPE_CODE_OR_MOBILE.equals(type)) {
				// 验证用户名或者手机号是否存在
				// 首先验证用户名是否存在
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("userCode", value);
				int rows = userService.checkUserUnique(params);
				if (rows > 0) {
					return false;
				}
				// 移除key
				params.remove(UserDataKey.VALID_TYPE_USER_CODE);
				// 手机号是否存在
				return checkMobileUnique(value);
			}else if (UserDataKey.CODE_MOBILE_CODE.equals(type)) {
				String verifyCodeKey = MyConstants.REGISTER_MOBILE_KEY.concat(mobile);
				// 手机验证码
				String mobileCode = redisService.get(verifyCodeKey);
				if (value.equals(mobileCode)) {
					return true;
				} else {
					return false;
				}
			} else if (UserDataKey.VALID_TYPE_MOBILE.equals(type)) {
				// 手机号是否存在
				return checkMobileUnique(value);
			} else if (UserDataKey.VALID_TYPE_USER_CODE.equals(type)) {
				// 用户名是否存在
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("userCode", value);
				int rows = userService.checkUserUnique(params);
				if (rows > 0) {
					return false;
				} else {
					return true;
				}
			} else if (UserDataKey.VALID_TYPE_COMPANY_MOBILE.equals(type)) {
				// 企业-验证手机校验
				return checkMobileUnique(value);
			} else if (UserDataKey.VALID_TYPE_COMPANY_NAME.equals(type)) {
				// 企业-公司名称校验
				Map<String, Object> param = new HashMap<String, Object>();
				param.put("companyName", value);
				List<CompanyEntity> companyList = companyService.listCompany(param);
				if (companyList != null && companyList.size() > 0) {
					return false;
				} else {
					return true;
				}
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 验证手机号是否被占用
	 * @return
	 * @author: solin
	 * @date: 2018年4月24日 下午3:07:58
	 */
	public boolean checkMobileUnique(String mobile) {
		// 判断手机号是否存在
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("mobile", mobile);
		List<CustomerEntity> customerList = customerService.listCustomer(param);
		if (customerList != null && customerList.size() > 0) {
			for (int i = 0; i < customerList.size(); i++) {
				if (!PublicStatus.USER_APPROVE_STATUS.REJECT.getId().equals(customerList.get(i).getStatus())) {
					return false;
				}
			}
			return true;
		} else {
			return true;
		}
	}

	/**
	 * 发送手机验证码
	 * 
	 * @param request
	 * @return
	 * @author: solin
	 * @date: 2017年11月16日 上午11:28:41
	 */
	@RequestMapping("/sendMobileCode")
	@ResponseBody
	public Map<String, Object> sendVerifyCode(HttpServletRequest request, String mobile) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// redis中的验证码KEY
			String verifyCodeKey = MyConstants.REGISTER_MOBILE_KEY.concat(mobile);
			// 发送短信
//			String templateId = "SMS_126866486";
			String verifyCode = RandomUtils.getRandNum(6);
			// 保存到redis
			redisService.save(verifyCodeKey, verifyCode, (30 * 60));
			Log.debug("============>>>短信验证码:" + verifyCode);
			String params = "{\"code\":\"" + verifyCode + "\"}";
			AliyunSmsUtils.sendSms(SmsTemplateType.SMS_REGISTER.getTemplateId(), mobile, params);
			
			resultMap.put("code", 1);
			resultMap.put("msg", "短信验证码发送成功！");
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", 0);
			resultMap.put("msg", "短信验证码发送失败！");
		}
		return resultMap;
	}

	/**
	 * 获取随机数
	 * 
	 * @param charCount
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月20日 下午7:25:57
	 */
	public String getRandNum(int charCount) {
		String charValue = "";
		for (int i = 0; i < charCount; i++) {
			char c = (char) (randomInt(0, 10) + '0');
			charValue += String.valueOf(c);
		}
		return charValue;
	}

	/**
	 * 通用
	 * 
	 * @param from
	 * @param to
	 * @return int
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月20日 下午7:26:16
	 */
	public int randomInt(int from, int to) {
		Random r = new Random();
		return from + r.nextInt(to - from);
	}

	/**
	 * 图片验证码生成
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 *             void
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月20日 下午7:21:02
	 */
	@RequestMapping("/autoCode.jpg")
	public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
		AuthCodeUtils util = null;
		try {
			// 通知浏览器不要缓存
			response.setHeader("Expires", "-1");
			response.setHeader("Cache-Control", "no-cache");
			response.setHeader("Pragma", "-1");
			util = AuthCodeUtils.Instance();
			// 将验证码输入到redis中，用来验证
			String code = util.getString();
			// 获取当前客户端公网IP，以此作为key
			String authKey = UserDataKey.CODE_AUTH_CODE + IPUtils.getIntenetIP(request);
			redisService.save(authKey, code);
			// request.getSession().setAttribute(UserDataKey.CODE_AUTH_CODE,
			// code);
			System.out.println("验证码：" + code);

			try {
				String osName = System.getProperty("os.name").toLowerCase();
				if (null != osName && osName.contains("win")) {
					ImageIO.write(util.getImage(), "jpg", new File("c:/" + code + ".jpg"));
				} else {
					ImageIO.write(util.getImage(), "jpg", new File("/usr/" + code + ".jpg"));
				}
			} catch (Exception e) {
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != util) {
				// 输出打web页面
				ImageIO.write(util.getImage(), "jpg", response.getOutputStream());
			}
		}

	}

	/**
	 * 转到注册页面
	 * 
	 * @param request
	 * @param model
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月19日 下午4:53:34
	 */
	@RequestMapping("/toRegPage")
	public String toRegPage(HttpServletRequest request, Model model) {
		try {

		} catch (Exception e) {
			e.printStackTrace();
		}
		return "pc/login/register";
	}
	
	/**
	 * 用户注册
	 * 
	 * @param request
	 * @param user
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月19日 下午4:55:22
	 */
	@RequestMapping("/userReg")
	@ResponseBody
	public BaseReturn userReg(HttpServletRequest request, CustomerEntity customer, CompanyEntity company, Model model, String mobileCode) {
		BaseReturn result = new BaseReturn();
		try {
			// 验证手机验证码
			String verifyCodeKey = MyConstants.REGISTER_MOBILE_KEY.concat(customer.getMobile());
			// redis中的验证码值
			String sendVerifyCode = redisService.get(verifyCodeKey);
			if (String.valueOf(mobileCode).equals(sendVerifyCode)) {
				// 校验成功后将验证码缓存清空
				redisService.del(verifyCodeKey);
			} else {
				result.setCode(SysCode.FAILED);
				result.setMsg("短信验证码输入不正确！");
				return result;
			}
			// 保存用户信息
			int resultCnt = customerService.registUserFromPc(customer,company);
			String authKey = UserDataKey.CODE_AUTH_CODE + customer.getMobile();
			redisService.del(authKey);
			result.setCode(resultCnt > 0 ? SysCode.SUCCESS : SysCode.ERROR);
			result.setMsg("用户注册成功！");
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			result.setCode(SysCode.ERROR);
			result.setMsg("用户注册异常！");
			return result;
		}
	}

	/**
	 * 邀请码生成
	 * 
	 * @Title: generateInvitationCode
	 * @Description:(描述)
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年10月18日 上午10:31:17
	 */
	public String generateInvitationCode() {
		try {
			String invitationCode = UUIDUtil.generateString(5);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("invitationCode", invitationCode);
			List<CustomerEntity> list = customerService.listCustomer(map);
			int count = 0;
			while (null != list && list.size() > 0) {
				// 说明该邀请码已被占用，需要重新生成
				invitationCode = UUIDUtil.generateString(5);
				map.put("invitationCode", invitationCode);
				list = customerService.listCustomer(map);
				count++;
				if (count > 100) {
					// 避免死循环，百次后直接返回
					return invitationCode;
				}
			}
			return invitationCode;
		} catch (Exception e) {
			e.printStackTrace();
			// 返回5位随机数
			return getRandNum(5);
		}
	}

}
